package org.innovasix.educational.javap.domain.parser;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;

import org.innovasix.educational.javap.domain.datatypes.u1;
import org.innovasix.educational.javap.domain.datatypes.u2;
import org.innovasix.educational.javap.domain.datatypes.u4;

public class ByteQueueImpl implements ByteQueue {

	private static final Logger log = Logger.getLogger(ByteQueueImpl.class.getName());
	
	DataInputStream dataInputStream;

	public ByteQueueImpl(InputStream inputStream){
		System.out.println(log.getLevel());
		dataInputStream = new DataInputStream(inputStream);
	}

	@Override
	public u1 pollOneByte(String currentUserID) {
		u1 retrievedValue = pollOneByteInternal();
		log(currentUserID, retrievedValue.getValue());
		return retrievedValue;
	}
	
	@Override
	public u1 pollOneByte() {
		return pollOneByte(null);
	}
	
	private u1 pollOneByteInternal() {
		try {
			int i = dataInputStream.readUnsignedByte();
			return new u1(i);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public u2 pollTwoBytes(String currentUserID) {
		u2 retrievedValue = pollTwoBytesInternal();
		log(currentUserID, retrievedValue.getValue());
		return retrievedValue;
	}
	
	@Override
	public u2 pollTwoBytes() {
		return pollTwoBytes(null);
	}
	
	private u2 pollTwoBytesInternal() {
		try {
			int high = dataInputStream.readUnsignedByte();
			int low = dataInputStream.readUnsignedByte();
			u2 retrievedValue = new u2(high,low);
			return retrievedValue;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@Override
	public u4 pollFourBytes(String currentUserID) {
		u4 retrievedValue = pollFourBytesInternal();
		log(currentUserID, retrievedValue.getValue());
		return retrievedValue;
	}
	
	@Override
	public u4 pollFourBytes() {
		return pollFourBytes(null);
	}

	private u4 pollFourBytesInternal() {
		try {
			return new u4(dataInputStream.readUnsignedByte(),dataInputStream.readUnsignedByte(),dataInputStream.readUnsignedByte(),dataInputStream.readUnsignedByte());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void log(String currentUserID, int value){
		if(currentUserID != null)
			log.finest(currentUserID + " retrives the value Ox" + Integer.toHexString(value) + " from the byte stream.");
		else
			log.finest("Unknown reader retrives the value Ox" + Integer.toHexString(value) + " from the byte stream.");
	}

}
